//
//  ILBindDefine.h
//  IMILabKit
//
//  Created by Roffa Zhou on 2022/3/21.
//

#import <Foundation/Foundation.h>
#import "ILBindDeviceModel.h"


NS_ASSUME_NONNULL_BEGIN
@class CBCharacteristic;
@class CBDescriptor;
@class CBService;

typedef NS_ENUM(NSUInteger, ILDiscoveryDeviceType){
    ILDiscoveryDeviceTypeWired,   //周围的有线设备
    ILDiscoveryDeviceTypeBLE,      //周围的蓝牙设备
};
#pragma mark - 绑定中错误
typedef NS_ENUM(NSInteger, ILBleStateError){
    //蓝牙状态相关错误
    ILBleStateError_Unauthorized = -105,   //蓝牙权限未开启
    ILBleStateError_PoweredOff = 301,      //蓝牙关闭
    ILBleStateError_Unknown = -103,      //蓝牙未知错误，建议重试
    ILBleStateError_Disconnect = -101,    //蓝牙断开连接
    ILBleStateError_Fail = -100,       //连接蓝牙设备失败
};
typedef NS_ENUM(NSInteger, ILBleCmdError){
    //蓝牙交互相关错误
    ILBleCmdError_Data_Invalid = 305,   //数据检查失败错误，可能丢失
    ILBleCmdError_Data_Fail = 1,  //操作失败
    ILBleCmdError_Data_Timeout = 2,  //蓝牙设备端返回超时错误,操作超时，请重试尝试
    ILBleCmdError_Data_Param = 3,      //参数错误
    ILBleCmdError_Data_Length = 4,   //数据长度错误
    ILBleCmdError_Data_Repeat = 5,   //重复密码错误
    ILBleCmdError_Data_User = 6,   //无用户
    ILBleCmdError_Data_Some = 7,   //部分操作成功
    ILBleCmdError_Data_Device = 8,   //设备内部中间过程返回错误
    ILBleCmdError_Data_Delete = 9,   //删除失败
    ILBleCmdError_Data_CRC = 10,   //数据CRC校验失败
    ILBleCmdError_Data_Finger = 11,   //指纹添加过程中，指纹区域重复
    ILBleCmdError_Data_Pwd = 12,   //用户修改密码与原密码不匹配
    ILBleCmdError_Data_Bind = 13,   //设备返回已绑定
    ILBleCmdError_Data_Property = 14,   //蓝牙没有获取到四元组/如果是带猫眼的设备则猫眼异常，反之则是蓝牙异常，一般不会出现，为设备bug
    ILBleCmdError_Data_Wifi = 15,   //带wifi 设备连接wfi失败
    ILBleCmdError_Data_Info = 16,   //wifi信息错误
    ILBleCmdError_Data_Shutdown = 17,   //猫眼未开机
    ILBleCmdError_Data_Unknown = 200,   //蓝牙发送的未知错误
    ILBleCmdError_Timeout_Discovery = -104,    //扫描目标设备失败
    ILBleCmdError_Timeout_Connect = -106,      //连接蓝牙设备超时失败
};
//参数异常相关报错
typedef NS_ENUM(NSInteger, ILBindParamError){
    ILBindParamError_DN = 1,
    ILBindParamError_PK = 2,
    ILBindParamError_PDA = 3,
    ILBindParamError_PDC = 4,
    ILBindParamError_DS = 5,
    ILBindParamError_PA = 6,
    ILBindParamError_SAPP = 7,


};

typedef NS_ENUM(NSUInteger, ILBindError){
    ILBindError_Null = 1000,                  ///错误初始化状态，此时未接收到具体错误
    ILBindError_Ble = 1001,                   ///蓝牙绑定相关错误
    ILBindError_Cloud_Secret_Get = 1002,           ///云端请求报错， 获取绑定密钥
    ILBindError_Cloud_Secret_Confirm = 1003,           ///云端请求报错， 绑定密钥确认
    ILBindError_Cloud_Secret_Login = 1004,         //云端请求报错，设备登录时
    ILBindError_Cloud_Bind_1 = 1005,               //云端请求报错，api/app_device/bind/v2
    ILBindError_Cloud_Bind_2 = 1006,               //云端请求报错，获取homeid失败
    ILBindError_Param = 1008,                       //参数错误, 网络请求前的字段检查
    /// 处理待绑定相关信息失败
    ILLinkError_PreInfo_Process_Faild = 1100,
    /// 预检查出错
    ILLinkError_Check_Faild = 1101,
    /// 发现设备失败
    /// 未发现指定设备 ILLinkSubError_Device_Not_Found
    /// 发现设备超时 ILLinkSubError_Found_Timeout
    ILLinkError_Discovery_Faild = 1102,
    /// 认证过程失败(获取token失败)
    ILLinkError_Verifying_Faild = 1103,
    /// 连接设备失败
    /// 连接失败 ILLinkSubError_Connect_Faild
    /// 连接超时 ILLinkSubError_Connect_Timeout
    ILLinkError_connect_Faild = 1104,
    /// 发送数据失败
    /// 待发送数据初始化失败 ILLinkSubError_Data_Init_Faild
    /// tcp创建失败 ILLinkSubError_Tcp_Creat_Faild
    /// tcp发送失败 ILLinkSubError_Tcp_Send_Faild
    /// udp创建失败 ILLinkSubError_Udp_Creat_Faild
    /// udp发送失败 ILLinkSubError_Udp_Send_Faild
    /// 发送数据超时 ILLinkSubError_Send_TimeOut
    ILLinkError_SendData_Faild = 1105,
    /// 配网失败
    ILLinkError_Setup_Net_Faild = 1106,
    /// 配置设备(调用绑定接口)失败
    ILLinkError_Cfg_Faild = 1107,
    /// 获取homeId失败
    ILLinkError_HomeId_Faild = 1108,
    /// 检查设备在线状态失败
    ILLinkError_CheckOnline_Faild = 1109,
    /// 获取设备信息失败
    ILLinkError_Product_Info_Faild = 1110,
    /// 激活设备失败
    ILLinkError_Invoke_Faild = 1111,
    /// 绑定超时
    ILLinkError_Timeout = 1112,
    /// 已被绑定
    ILLinkError_HaveBind = 1113,
};

#pragma mark - 绑定中状态
typedef NS_ENUM(NSUInteger, ILBindConnectMode){  //连接状态细节
    ILBindConnectMode_Ble_Connect = 2201,               //连接蓝牙设备中
    ILBindConnectMode_Ble_Services = 2202,              //发现蓝牙服务中
    ILBindConnectMode_Ble_Characteristics = 2203,             //发现蓝牙特征中
    ILBindConnectMode_Ble_Notify = 2204,                      //发起通知监听中
};
typedef NS_ENUM(NSUInteger, ILBindVerifyMode){  //认证状态细节
    ILBindVerifyMode_DN = 2401,              //获取蓝牙 dn+pda+pdc
    ILBindVerifyMode_Ack = 2402,                   //向设备确认开始绑定通讯
    ILBindVerifyMode_PA = 2403,                    //从服务器获取的认证信息发送给设备
    ILBindVerifyMode_Secret = 2404,               //向服务器进行密钥确认
    ILBindVerifyMode_Bind = 2405,                 //向服务器发送绑定请求
    ILBindVerifyMode_Fin = 2406,                  //向设备发送绑定完成
};
typedef NS_ENUM(NSUInteger, ILBindLoginMode){
    ILBindLoginMode_Secret = 2501,        //获取登录密钥
    ILBindLoginMode_PA = 2502,            //从服务器获取的认证信息发送给设备
};
typedef NS_ENUM(NSUInteger, ILBindCfgMode){
    ILBindCfgMode_Get = 2601,        //获取设备是否已配置wifi
    ILBindCfgMode_Wifi = 2602,        //设置设备wifi信息
    ILBindCfgMode_HomeId = 2603,        //从云端获取homeId中
    ILBindCfgMode_Bind = 2604,        //绑定WiFi设备中
    ILBindCfgMode_Fin = 2605,        //配置完成

};
typedef NS_ENUM(NSUInteger, ILBindMode){
    ILBindMode_Null = 2000,             ///初始化状态，此时未进入绑定流程
    ILBindMode_Discovering = 2100,              ///发现中
    ILBindMode_Connecting = 2200,              ///连接中
    ILBindMode_Parsing = 2300,               ///解析数据中
    ILBindMode_Verifying = 2400,               ///认证中
    ILBindMode_Login = 2500,               //蓝牙登录中
    ILBindMode_Cfg = 2600,                 //蓝牙设备相关配置
};

/**
 云端报错子码如下
 -1    获取设备四元组错误（云端异常）    提交工单给云服务
 -2    云服务未找到此设备    提交问题给设备侧/云服务侧
 -3    当前用户没有该设备的lmtk记录    提交工单给云服务侧
 -4    提交注册确认消息异常    提交工单给云服务侧
 -8    设备已被绑定    请联系管理员解绑
 */

typedef void (^IL_Bind_Ble_Device_Block)(ILBindDeviceModel * _Nonnull peripheral,  NSError * _Nullable error);  //蓝牙绑定过程返回
typedef void (^IL_Bind_Ble_Device_Service_Block)(ILBindDeviceModel * _Nonnull peripheral, NSArray<CBService *> * _Nonnull cbServices, NSError * _Nullable error);  //蓝牙绑定过程返回
typedef void (^IL_Bind_Ble_Mac_Block)(ILBindDeviceModel * _Nonnull peripheral, NSString* _Nullable mac);  //蓝牙获取到mac返回
typedef void (^IL_Bind_Ble_Device_Default_Block)(ILBindDeviceModel * _Nonnull peripheral, CBCharacteristic * _Nonnull characteristic,  NSError * _Nullable error);  //蓝牙回调，
typedef void (^IL_Bind_Ble_Device_Data_Block)(ILBindDeviceModel * _Nonnull peripheral, CBCharacteristic * _Nonnull characteristic, NSData * _Nullable data);  //蓝牙绑定交互过程中，一次通讯,接收完所有的的包数据，会触发此回调
typedef void (^IL_Bind_Ble_Device_Descriptor_Block)(ILBindDeviceModel * _Nonnull peripheral, CBDescriptor * _Nonnull descriptor, NSError * _Nullable error);  //写入descriptor回调
typedef void (^IL_Bind_Ble_Device_Characteristic_Block)(ILBindDeviceModel * _Nonnull peripheral, CBService * _Nonnull service, NSArray<CBCharacteristic *> * _Nonnull characteristics, NSError * _Nullable error);  //写入descriptor回调
typedef void (^IL_Bind_Ble_State_Block)(short state);  //蓝牙状态改变回调
///重试回调
typedef void(^ILBindRetryBlock)(void);


@interface ILBindBaseModel : NSObject
@property(nonatomic)NSInteger subCode;      //绑定二级子码， 如:ILBleError, 当不存在子码，将返回0
@property(nonatomic, copy)NSString *message;    //状态信息，只作为调试信息提示，内部不做国际化处理
@end

/// 绑定中状态
@interface ILBindModeModel : ILBindBaseModel
@property(nonatomic)ILBindMode mode;
- (void)updateBindMode:(ILBindMode)mode subCode:(NSInteger)subCode;
@end

/// 绑定报错
@interface ILBindErrorModel : ILBindBaseModel
@property(nonatomic)ILBindError code;      //绑定错误一级错误
@property(nonatomic, copy)NSString *suggest;  //处理建议，只作为调试信息提示，内部不做国际化处理
@property(nonatomic, assign)BOOL canRetry;  // 该错误是否可以重试,如果可以,可以调用重试接口
- (void)updateBindError:(ILBindError)bindError subCode:(NSInteger)subCode canRetry:(BOOL)canRetry;
@end

typedef void (^IL_Bind_Discovery_Block)(ILBindDeviceModel *peripheral, NSArray<ILBindDeviceModel *> *devices, BOOL scanEnd);//找到设备的委托
typedef void (^IL_Bind_Error_Block)(ILBindErrorModel *error);//当出现绑定流程中报错时，会响应此block
typedef void (^IL_Bind_Mode_Block)(ILBindModeModel *mode);//当出现绑定流程中状态变更时，会响应此block
typedef void (^IL_Ble_Mode1_Succ_Block)(NSString* deviceName, NSString *productKey, NSString*mac);         //蓝牙通讯过程中，使用mode1模式绑定后回调。用户应该在此回调中完成首次具体的绑定请求操作binding:，绑定成功后，在调用ILBleObject中提供的方法wakeUpBleRegister:
typedef void (^IL_Ble_Mode2_Succ_Block)(NSString* deviceName, NSString* token);         //蓝牙通讯过程中，使用mode2模式绑定后回调。在此回调中调用如bindingWifi:方法绑定

typedef void (^IL_Bind_Api_Succ_Block)(NSDictionary*dict);//mode_1绑定最后一步的绑定网络请求API成功，会响应此block
typedef void (^IL_Ble_Mode2_Result_Block)(BOOL result); //蓝牙登录或是否已连接wifi结果回调，返回登录结果

@interface ILBindDefine : NSObject

@end

NS_ASSUME_NONNULL_END
